package commons

import (
	"bytes"
	"crypto/md5"
	crand "crypto/rand"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"reflect"
	"strconv"
	"strings"

	"goweb/ext/settings"
)

/**
 * string转换int
 * @method parseInt
 * @param  {[type]} b string        [description]
 * @return {[type]}   [description]
 */
func ParseInt(b string, defInt int) string {
	_, err := strconv.Atoi(b)
	if err != nil {
		conf.Logger.Error("parseInt", err)
		return conf.STRING_FLAG
	} else {
		return b
	}
}

/**
字符串拼接
*/
func StringJoin(a []string) string {
	var buf bytes.Buffer
	for _, k := range a {
		buf.WriteString(k)
	}
	fmt.Println(buf.String())
	return buf.String()
}

/**
 * int转换string
 * @method parseInt
 * @param  {[type]} b string        [description]
 * @return {[type]}   [description]
 */
func ParseString(b int) string {
	id := strconv.Itoa(b)
	return id
}

/**
 * 转换浮点数为string
 * @method func
 * @param  {[type]} t *             Tools [description]
 * @return {[type]}   [description]
 */
func ParseFlostToString(f float64) string {
	return strconv.FormatFloat(f, 'f', 5, 64)
}

/**
 * md5 加密
 * @method MD5
 * @param  {[type]} data string [description]
 */
func MD5(data string) string {
	_m := md5.New()
	io.WriteString(_m, data)
	return fmt.Sprintf("%x", _m.Sum(nil))
}

func EncodeMd5(value string) string {

	m := md5.New()
	m.Write([]byte(value))

	return hex.EncodeToString(m.Sum(nil))
}

func StrToInter(s string) (int, error) {

	at, err := strconv.Atoi(s)

	if !CheckErr(err) {
		return at, err
	}

	return at, nil

}

func IsEmpty(s string) bool {
	if strings.TrimSpace(s) != "" {
		return true
	}
	return false
}

/**
 * 结构体转成json 字符串
 * @method StruckToString
 * @param  {[type]}       data interface{} [description]
 */
func StructToString(data interface{}) string {
	b, err := json.Marshal(data)
	if err != nil {
		return err.Error()
	} else {
		return string(b)
	}
}

/**
 * 结构体转换成map对象
 * @method func
 * @param  {[type]} t *Tools        [description]
 * @return {[type]}   [description]
 */
func StructToMap(obj interface{}) map[string]interface{} {
	k := reflect.TypeOf(obj)
	v := reflect.ValueOf(obj)

	var data = make(map[string]interface{})
	for i := 0; i < k.NumField(); i++ {
		data[strings.ToLower(k.Field(i).Name)] = v.Field(i).Interface()
	}
	return data
}

//生成随机字符串
func GetRandomString(n int) string {
	const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()+[]{}/<>;:=.,?"
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))]
	}
	return string(b)
}

/**
 * 字符串截取
 * @method func
 * @param  {[type]} t *Tools        [description]
 * @return {[type]}   [description]
 */
func SubString(str string, start, length int) string {
	if length == 0 {
		return ""
	}
	rune_str := []rune(str)
	len_str := len(rune_str)

	if start < 0 {
		start = len_str + start
	}
	if start > len_str {
		start = len_str
	}
	end := start + length
	if end > len_str {
		end = len_str
	}
	if length < 0 {
		end = len_str + length
	}
	if start > end {
		start, end = end, start
	}
	return string(rune_str[start:end])
}

/**
 * base64 解码
 * @method func
 * @param  {[type]} t *Tools        [description]
 * @return {[type]}   [description]
 */
func Base64Decode(str string) string {
	s, err := base64.StdEncoding.DecodeString(str)
	if err != nil {
		return ""
	}
	return string(s)
}

func PostBody(body []byte) map[string]interface{} {
	bodyMap := make(map[string]interface{})
	json.Unmarshal(body, &bodyMap)
	return bodyMap
}

// 请求参数（不带Cookies）
func GetUrlRespHtml(strUrl string, postDict map[string]string) string {
	var respHtml string = ""
	var httpReq *http.Request
	httpClient := &http.Client{}
	if nil == postDict {
		httpReq, _ = http.NewRequest("GET", strUrl, nil)
	} else {
		postValues := url.Values{}
		for postKey, PostValue := range postDict {
			postValues.Set(postKey, PostValue)
		}
		postDataStr := postValues.Encode()
		postDataBytes := []byte(postDataStr)
		postBytesReader := bytes.NewReader(postDataBytes)
		fmt.Println(strUrl, postValues)
		httpReq, _ = http.NewRequest("POST", strUrl, postBytesReader)
		httpReq.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	}
	httpResp, err := httpClient.Do(httpReq)
	if err != nil {
		//		fmt.Println("http get strUrl= response error=\n", strUrl, err.Error())
	}
	defer httpResp.Body.Close()
	body, errReadAll := ioutil.ReadAll(httpResp.Body)
	if errReadAll != nil {
		fmt.Println("get response for strUrl= got error=\n", strUrl, errReadAll.Error())
	}
	respHtml = string(body)
	return respHtml
}

// PathExists 判断文件或文件夹是否存在,true存在,false不存在
func PathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	return false
}

// GetMd5String 生成32位md5字串
func GetMd5String(s string) string {
	h := md5.New()
	h.Write([]byte(s))
	return hex.EncodeToString(h.Sum(nil))
}

// GUID 生成Guid字串
func GUID() string {
	b := make([]byte, 48)
	if _, err := io.ReadFull(crand.Reader, b); err != nil {
		return ""
	}
	return GetMd5String(base64.URLEncoding.EncodeToString(b))
}

func ParseUrl(target string) (schema, domain, port, path string) {

	// https://www.baidu.com
	targetArr := strings.Split(target, "//")
	schema = targetArr[0]

	href := strings.Split(targetArr[1], "/")

	//判断是否有其他端口

	addrArr := strings.Split(href[0], ":")

	if len(addrArr) == 2 {
		domain = addrArr[0]
		port = addrArr[1]
	} else {
		domain = href[0]
	}
	for _, seg := range href[1:] {
		path += ("/" + seg)
	}

	return
}
